Added a "volumes-changed" signal. Added the following methods:
authorFederico Mena Quintero <federico@ximian.com>
Wed, 17 Dec 2003 05:55:16 +0000 (05:55 +0000)
committerFederico Mena Quintero <federico@src.gnome.org>
Wed, 17 Dec 2003 05:55:16 +0000 (05:55 +0000)
2003-12-16  Federico Mena Quintero  <federico@ximian.com>

* gtk/gtkfilesystem.h (struct _GtkFileSystemIface): Added a
"volumes-changed" signal.  Added the following methods:
list_volumes
volume_free
volume_get_base_path
volume_get_is_mounted
volume_mount
volume_get_display_name
volume_render_icon

* gtk/gtkfilesystem.c (gtk_file_system_base_init): Create the
"volumes-changed" signal.
(gtk_file_system_list_volumes): New function.
(gtk_file_system_volume_free): New function.
(gtk_file_system_volume_get_base_path): New function.
(gtk_file_system_volume_get_is_mounted): New function.
(gtk_file_system_volume_mount): New function.
(gtk_file_system_volume_get_display_name): New function.
(gtk_file_system_volume_render_icon): New function.

* gtk/gtkfilesystemunix.c (gtk_file_system_unix_volume_free): Implement.
(gtk_file_system_unix_volume_get_base_path): Implement.
(gtk_file_system_unix_volume_get_is_mounted): Implement.
(gtk_file_system_unix_volume_mount): Implement.
(gtk_file_system_unix_volume_get_display_name): Implement.
(gtk_file_system_unix_volume_render_icon): Implement.

* gtk/gtkfilechooserdefault.c (struct _GtkFileChooserDefault):
Added a field for the "volumes-changed" signal connection.
(gtk_file_chooser_default_set_property): Connect to
"volumes-changed" on the file system.
(gtk_file_chooser_default_finalize): Disconnect from
"volumes-changed".

* gtk/gtkfilechooserdefault.c (shortcuts_remove_rows): New helper
function.
(shortcuts_get_index): New helper function.
(shortcuts_insert_path): Can now insert volumes as well as paths.
(shortcuts_append_paths): Don't take is_file_system_root.
(shortcuts_add_volumes): New function.
(shortcuts_append_file_system_roots): Removed.
(create_shortcuts_model): Use shortcuts_add_volumes().
(remove_bookmark_button_clicked_cb): Check that the index is
within range.
(bookmarks_check_add_sensitivity): Take volumes into account.
(shortcuts_get_selected_index): New helper function.
(remove_bookmark_button_clicked_cb): Use
shortcuts_get_selected_index().
(bookmarks_check_remove_sensitivity): Likewise.
(shortcuts_select_func): Likewise.
(shortcuts_row_activated_cb): Handle volumes as well as normal
paths.
(shortcuts_activate_volume): New function.
(struct _GtkFileChooserDefault): Removed the bookmarks_set and
bookmarks_iter fields.
(shortcuts_append_bookmarks): Use shortcuts_remove_rows().
(bookmarks_changed_cb): Use shortcuts_add_bookmarks().
(remove_bookmark_rows): Removed.
(shortcuts_add_bookmarks): New function; moved most of the code
over from shortcuts_append_bookmarks().
(shortcuts_append_bookmarks): Add the separator node here, and
then call shortcuts_add_bookmarks().

ChangeLog
ChangeLog.pre-2-10
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
gtk/gtkfilechooserdefault.c
gtk/gtkfilesystem.c
gtk/gtkfilesystem.h
gtk/gtkfilesystemunix.c

index 37c51ce5f0042f347d9d154e80d4a65e9c2ccd79..946835be5fe9958c631db027ae10ce9e5058fce1 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,68 @@
+2003-12-16  Federico Mena Quintero  <federico@ximian.com>
+
+       * gtk/gtkfilesystem.h (struct _GtkFileSystemIface): Added a
+       "volumes-changed" signal.  Added the following methods:
+               list_volumes
+               volume_free
+               volume_get_base_path
+               volume_get_is_mounted
+               volume_mount
+               volume_get_display_name
+               volume_render_icon
+
+       * gtk/gtkfilesystem.c (gtk_file_system_base_init): Create the
+       "volumes-changed" signal.
+       (gtk_file_system_list_volumes): New function.
+       (gtk_file_system_volume_free): New function.
+       (gtk_file_system_volume_get_base_path): New function.
+       (gtk_file_system_volume_get_is_mounted): New function.
+       (gtk_file_system_volume_mount): New function.
+       (gtk_file_system_volume_get_display_name): New function.
+       (gtk_file_system_volume_render_icon): New function.
+
+       * gtk/gtkfilesystemunix.c (gtk_file_system_unix_volume_free): Implement.
+       (gtk_file_system_unix_volume_get_base_path): Implement.
+       (gtk_file_system_unix_volume_get_is_mounted): Implement.
+       (gtk_file_system_unix_volume_mount): Implement.
+       (gtk_file_system_unix_volume_get_display_name): Implement.
+       (gtk_file_system_unix_volume_render_icon): Implement.
+
+       * gtk/gtkfilechooserdefault.c (struct _GtkFileChooserDefault):
+       Added a field for the "volumes-changed" signal connection.
+       (gtk_file_chooser_default_set_property): Connect to
+       "volumes-changed" on the file system.
+       (gtk_file_chooser_default_finalize): Disconnect from
+       "volumes-changed".
+
+       * gtk/gtkfilechooserdefault.c (shortcuts_remove_rows): New helper
+       function.
+       (shortcuts_get_index): New helper function.
+       (shortcuts_insert_path): Can now insert volumes as well as paths.
+       (shortcuts_append_paths): Don't take is_file_system_root.
+       (shortcuts_add_volumes): New function.
+       (shortcuts_append_file_system_roots): Removed.
+       (create_shortcuts_model): Use shortcuts_add_volumes().
+       (remove_bookmark_button_clicked_cb): Check that the index is
+       within range.
+       (bookmarks_check_add_sensitivity): Take volumes into account.
+       (shortcuts_get_selected_index): New helper function.
+       (remove_bookmark_button_clicked_cb): Use
+       shortcuts_get_selected_index().
+       (bookmarks_check_remove_sensitivity): Likewise.
+       (shortcuts_select_func): Likewise.
+       (shortcuts_row_activated_cb): Handle volumes as well as normal
+       paths.
+       (shortcuts_activate_volume): New function.
+       (struct _GtkFileChooserDefault): Removed the bookmarks_set and
+       bookmarks_iter fields.
+       (shortcuts_append_bookmarks): Use shortcuts_remove_rows().
+       (bookmarks_changed_cb): Use shortcuts_add_bookmarks().
+       (remove_bookmark_rows): Removed.
+       (shortcuts_add_bookmarks): New function; moved most of the code
+       over from shortcuts_append_bookmarks().
+       (shortcuts_append_bookmarks): Add the separator node here, and
+       then call shortcuts_add_bookmarks().
+
 Tue Dec 16 15:01:10 2003  Manish Singh  <yosh@gimp.org>
 
        * gtk/gtkfilechooserwidget.c: fix preprocessor conditional confusion.
index 37c51ce5f0042f347d9d154e80d4a65e9c2ccd79..946835be5fe9958c631db027ae10ce9e5058fce1 100644 (file)
@@ -1,3 +1,68 @@
+2003-12-16  Federico Mena Quintero  <federico@ximian.com>
+
+       * gtk/gtkfilesystem.h (struct _GtkFileSystemIface): Added a
+       "volumes-changed" signal.  Added the following methods:
+               list_volumes
+               volume_free
+               volume_get_base_path
+               volume_get_is_mounted
+               volume_mount
+               volume_get_display_name
+               volume_render_icon
+
+       * gtk/gtkfilesystem.c (gtk_file_system_base_init): Create the
+       "volumes-changed" signal.
+       (gtk_file_system_list_volumes): New function.
+       (gtk_file_system_volume_free): New function.
+       (gtk_file_system_volume_get_base_path): New function.
+       (gtk_file_system_volume_get_is_mounted): New function.
+       (gtk_file_system_volume_mount): New function.
+       (gtk_file_system_volume_get_display_name): New function.
+       (gtk_file_system_volume_render_icon): New function.
+
+       * gtk/gtkfilesystemunix.c (gtk_file_system_unix_volume_free): Implement.
+       (gtk_file_system_unix_volume_get_base_path): Implement.
+       (gtk_file_system_unix_volume_get_is_mounted): Implement.
+       (gtk_file_system_unix_volume_mount): Implement.
+       (gtk_file_system_unix_volume_get_display_name): Implement.
+       (gtk_file_system_unix_volume_render_icon): Implement.
+
+       * gtk/gtkfilechooserdefault.c (struct _GtkFileChooserDefault):
+       Added a field for the "volumes-changed" signal connection.
+       (gtk_file_chooser_default_set_property): Connect to
+       "volumes-changed" on the file system.
+       (gtk_file_chooser_default_finalize): Disconnect from
+       "volumes-changed".
+
+       * gtk/gtkfilechooserdefault.c (shortcuts_remove_rows): New helper
+       function.
+       (shortcuts_get_index): New helper function.
+       (shortcuts_insert_path): Can now insert volumes as well as paths.
+       (shortcuts_append_paths): Don't take is_file_system_root.
+       (shortcuts_add_volumes): New function.
+       (shortcuts_append_file_system_roots): Removed.
+       (create_shortcuts_model): Use shortcuts_add_volumes().
+       (remove_bookmark_button_clicked_cb): Check that the index is
+       within range.
+       (bookmarks_check_add_sensitivity): Take volumes into account.
+       (shortcuts_get_selected_index): New helper function.
+       (remove_bookmark_button_clicked_cb): Use
+       shortcuts_get_selected_index().
+       (bookmarks_check_remove_sensitivity): Likewise.
+       (shortcuts_select_func): Likewise.
+       (shortcuts_row_activated_cb): Handle volumes as well as normal
+       paths.
+       (shortcuts_activate_volume): New function.
+       (struct _GtkFileChooserDefault): Removed the bookmarks_set and
+       bookmarks_iter fields.
+       (shortcuts_append_bookmarks): Use shortcuts_remove_rows().
+       (bookmarks_changed_cb): Use shortcuts_add_bookmarks().
+       (remove_bookmark_rows): Removed.
+       (shortcuts_add_bookmarks): New function; moved most of the code
+       over from shortcuts_append_bookmarks().
+       (shortcuts_append_bookmarks): Add the separator node here, and
+       then call shortcuts_add_bookmarks().
+
 Tue Dec 16 15:01:10 2003  Manish Singh  <yosh@gimp.org>
 
        * gtk/gtkfilechooserwidget.c: fix preprocessor conditional confusion.
index 37c51ce5f0042f347d9d154e80d4a65e9c2ccd79..946835be5fe9958c631db027ae10ce9e5058fce1 100644 (file)
@@ -1,3 +1,68 @@
+2003-12-16  Federico Mena Quintero  <federico@ximian.com>
+
+       * gtk/gtkfilesystem.h (struct _GtkFileSystemIface): Added a
+       "volumes-changed" signal.  Added the following methods:
+               list_volumes
+               volume_free
+               volume_get_base_path
+               volume_get_is_mounted
+               volume_mount
+               volume_get_display_name
+               volume_render_icon
+
+       * gtk/gtkfilesystem.c (gtk_file_system_base_init): Create the
+       "volumes-changed" signal.
+       (gtk_file_system_list_volumes): New function.
+       (gtk_file_system_volume_free): New function.
+       (gtk_file_system_volume_get_base_path): New function.
+       (gtk_file_system_volume_get_is_mounted): New function.
+       (gtk_file_system_volume_mount): New function.
+       (gtk_file_system_volume_get_display_name): New function.
+       (gtk_file_system_volume_render_icon): New function.
+
+       * gtk/gtkfilesystemunix.c (gtk_file_system_unix_volume_free): Implement.
+       (gtk_file_system_unix_volume_get_base_path): Implement.
+       (gtk_file_system_unix_volume_get_is_mounted): Implement.
+       (gtk_file_system_unix_volume_mount): Implement.
+       (gtk_file_system_unix_volume_get_display_name): Implement.
+       (gtk_file_system_unix_volume_render_icon): Implement.
+
+       * gtk/gtkfilechooserdefault.c (struct _GtkFileChooserDefault):
+       Added a field for the "volumes-changed" signal connection.
+       (gtk_file_chooser_default_set_property): Connect to
+       "volumes-changed" on the file system.
+       (gtk_file_chooser_default_finalize): Disconnect from
+       "volumes-changed".
+
+       * gtk/gtkfilechooserdefault.c (shortcuts_remove_rows): New helper
+       function.
+       (shortcuts_get_index): New helper function.
+       (shortcuts_insert_path): Can now insert volumes as well as paths.
+       (shortcuts_append_paths): Don't take is_file_system_root.
+       (shortcuts_add_volumes): New function.
+       (shortcuts_append_file_system_roots): Removed.
+       (create_shortcuts_model): Use shortcuts_add_volumes().
+       (remove_bookmark_button_clicked_cb): Check that the index is
+       within range.
+       (bookmarks_check_add_sensitivity): Take volumes into account.
+       (shortcuts_get_selected_index): New helper function.
+       (remove_bookmark_button_clicked_cb): Use
+       shortcuts_get_selected_index().
+       (bookmarks_check_remove_sensitivity): Likewise.
+       (shortcuts_select_func): Likewise.
+       (shortcuts_row_activated_cb): Handle volumes as well as normal
+       paths.
+       (shortcuts_activate_volume): New function.
+       (struct _GtkFileChooserDefault): Removed the bookmarks_set and
+       bookmarks_iter fields.
+       (shortcuts_append_bookmarks): Use shortcuts_remove_rows().
+       (bookmarks_changed_cb): Use shortcuts_add_bookmarks().
+       (remove_bookmark_rows): Removed.
+       (shortcuts_add_bookmarks): New function; moved most of the code
+       over from shortcuts_append_bookmarks().
+       (shortcuts_append_bookmarks): Add the separator node here, and
+       then call shortcuts_add_bookmarks().
+
 Tue Dec 16 15:01:10 2003  Manish Singh  <yosh@gimp.org>
 
        * gtk/gtkfilechooserwidget.c: fix preprocessor conditional confusion.
index 37c51ce5f0042f347d9d154e80d4a65e9c2ccd79..946835be5fe9958c631db027ae10ce9e5058fce1 100644 (file)
@@ -1,3 +1,68 @@
+2003-12-16  Federico Mena Quintero  <federico@ximian.com>
+
+       * gtk/gtkfilesystem.h (struct _GtkFileSystemIface): Added a
+       "volumes-changed" signal.  Added the following methods:
+               list_volumes
+               volume_free
+               volume_get_base_path
+               volume_get_is_mounted
+               volume_mount
+               volume_get_display_name
+               volume_render_icon
+
+       * gtk/gtkfilesystem.c (gtk_file_system_base_init): Create the
+       "volumes-changed" signal.
+       (gtk_file_system_list_volumes): New function.
+       (gtk_file_system_volume_free): New function.
+       (gtk_file_system_volume_get_base_path): New function.
+       (gtk_file_system_volume_get_is_mounted): New function.
+       (gtk_file_system_volume_mount): New function.
+       (gtk_file_system_volume_get_display_name): New function.
+       (gtk_file_system_volume_render_icon): New function.
+
+       * gtk/gtkfilesystemunix.c (gtk_file_system_unix_volume_free): Implement.
+       (gtk_file_system_unix_volume_get_base_path): Implement.
+       (gtk_file_system_unix_volume_get_is_mounted): Implement.
+       (gtk_file_system_unix_volume_mount): Implement.
+       (gtk_file_system_unix_volume_get_display_name): Implement.
+       (gtk_file_system_unix_volume_render_icon): Implement.
+
+       * gtk/gtkfilechooserdefault.c (struct _GtkFileChooserDefault):
+       Added a field for the "volumes-changed" signal connection.
+       (gtk_file_chooser_default_set_property): Connect to
+       "volumes-changed" on the file system.
+       (gtk_file_chooser_default_finalize): Disconnect from
+       "volumes-changed".
+
+       * gtk/gtkfilechooserdefault.c (shortcuts_remove_rows): New helper
+       function.
+       (shortcuts_get_index): New helper function.
+       (shortcuts_insert_path): Can now insert volumes as well as paths.
+       (shortcuts_append_paths): Don't take is_file_system_root.
+       (shortcuts_add_volumes): New function.
+       (shortcuts_append_file_system_roots): Removed.
+       (create_shortcuts_model): Use shortcuts_add_volumes().
+       (remove_bookmark_button_clicked_cb): Check that the index is
+       within range.
+       (bookmarks_check_add_sensitivity): Take volumes into account.
+       (shortcuts_get_selected_index): New helper function.
+       (remove_bookmark_button_clicked_cb): Use
+       shortcuts_get_selected_index().
+       (bookmarks_check_remove_sensitivity): Likewise.
+       (shortcuts_select_func): Likewise.
+       (shortcuts_row_activated_cb): Handle volumes as well as normal
+       paths.
+       (shortcuts_activate_volume): New function.
+       (struct _GtkFileChooserDefault): Removed the bookmarks_set and
+       bookmarks_iter fields.
+       (shortcuts_append_bookmarks): Use shortcuts_remove_rows().
+       (bookmarks_changed_cb): Use shortcuts_add_bookmarks().
+       (remove_bookmark_rows): Removed.
+       (shortcuts_add_bookmarks): New function; moved most of the code
+       over from shortcuts_append_bookmarks().
+       (shortcuts_append_bookmarks): Add the separator node here, and
+       then call shortcuts_add_bookmarks().
+
 Tue Dec 16 15:01:10 2003  Manish Singh  <yosh@gimp.org>
 
        * gtk/gtkfilechooserwidget.c: fix preprocessor conditional confusion.
index 37c51ce5f0042f347d9d154e80d4a65e9c2ccd79..946835be5fe9958c631db027ae10ce9e5058fce1 100644 (file)
@@ -1,3 +1,68 @@
+2003-12-16  Federico Mena Quintero  <federico@ximian.com>
+
+       * gtk/gtkfilesystem.h (struct _GtkFileSystemIface): Added a
+       "volumes-changed" signal.  Added the following methods:
+               list_volumes
+               volume_free
+               volume_get_base_path
+               volume_get_is_mounted
+               volume_mount
+               volume_get_display_name
+               volume_render_icon
+
+       * gtk/gtkfilesystem.c (gtk_file_system_base_init): Create the
+       "volumes-changed" signal.
+       (gtk_file_system_list_volumes): New function.
+       (gtk_file_system_volume_free): New function.
+       (gtk_file_system_volume_get_base_path): New function.
+       (gtk_file_system_volume_get_is_mounted): New function.
+       (gtk_file_system_volume_mount): New function.
+       (gtk_file_system_volume_get_display_name): New function.
+       (gtk_file_system_volume_render_icon): New function.
+
+       * gtk/gtkfilesystemunix.c (gtk_file_system_unix_volume_free): Implement.
+       (gtk_file_system_unix_volume_get_base_path): Implement.
+       (gtk_file_system_unix_volume_get_is_mounted): Implement.
+       (gtk_file_system_unix_volume_mount): Implement.
+       (gtk_file_system_unix_volume_get_display_name): Implement.
+       (gtk_file_system_unix_volume_render_icon): Implement.
+
+       * gtk/gtkfilechooserdefault.c (struct _GtkFileChooserDefault):
+       Added a field for the "volumes-changed" signal connection.
+       (gtk_file_chooser_default_set_property): Connect to
+       "volumes-changed" on the file system.
+       (gtk_file_chooser_default_finalize): Disconnect from
+       "volumes-changed".
+
+       * gtk/gtkfilechooserdefault.c (shortcuts_remove_rows): New helper
+       function.
+       (shortcuts_get_index): New helper function.
+       (shortcuts_insert_path): Can now insert volumes as well as paths.
+       (shortcuts_append_paths): Don't take is_file_system_root.
+       (shortcuts_add_volumes): New function.
+       (shortcuts_append_file_system_roots): Removed.
+       (create_shortcuts_model): Use shortcuts_add_volumes().
+       (remove_bookmark_button_clicked_cb): Check that the index is
+       within range.
+       (bookmarks_check_add_sensitivity): Take volumes into account.
+       (shortcuts_get_selected_index): New helper function.
+       (remove_bookmark_button_clicked_cb): Use
+       shortcuts_get_selected_index().
+       (bookmarks_check_remove_sensitivity): Likewise.
+       (shortcuts_select_func): Likewise.
+       (shortcuts_row_activated_cb): Handle volumes as well as normal
+       paths.
+       (shortcuts_activate_volume): New function.
+       (struct _GtkFileChooserDefault): Removed the bookmarks_set and
+       bookmarks_iter fields.
+       (shortcuts_append_bookmarks): Use shortcuts_remove_rows().
+       (bookmarks_changed_cb): Use shortcuts_add_bookmarks().
+       (remove_bookmark_rows): Removed.
+       (shortcuts_add_bookmarks): New function; moved most of the code
+       over from shortcuts_append_bookmarks().
+       (shortcuts_append_bookmarks): Add the separator node here, and
+       then call shortcuts_add_bookmarks().
+
 Tue Dec 16 15:01:10 2003  Manish Singh  <yosh@gimp.org>
 
        * gtk/gtkfilechooserwidget.c: fix preprocessor conditional confusion.
index 86aec4c320ec94b73a7f547b5bf65fbc1a7aca09..0b037895cc3d6db9614f6535e4933ab7e44661b5 100644 (file)
@@ -85,12 +85,14 @@ struct _GtkFileChooserDefault
 
   gboolean has_home;
   gboolean has_desktop;
-  int num_roots;
+
+  int num_volumes;
   int num_shortcuts;
   int num_bookmarks;
 
+  guint volumes_changed_id;
+
   guint bookmarks_changed_id;
-  GtkTreeIter bookmarks_iter;
 
   GtkFilePath *current_folder;
   GtkFilePath *preview_path;
@@ -122,7 +124,6 @@ struct _GtkFileChooserDefault
   guint select_multiple : 1;
   guint show_hidden : 1;
   guint list_sort_ascending : 1;
-  guint bookmarks_set : 1;
   guint changing_folder : 1;
 };
 
@@ -154,6 +155,16 @@ static GtkTargetEntry shortcuts_targets[] = {
 
 static const int num_shortcuts_targets = sizeof (shortcuts_targets) / sizeof (shortcuts_targets[0]);
 
+/* Interesting places in the shortcuts bar */
+typedef enum {
+  SHORTCUTS_HOME,
+  SHORTCUTS_DESKTOP,
+  SHORTCUTS_VOLUMES,
+  SHORTCUTS_SHORTCUTS,
+  SHORTCUTS_SEPARATOR,
+  SHORTCUTS_BOOKMARKS
+} ShortcutsIndex;
+
 /* Standard icon size */
 /* FIXME: maybe this should correspond to the font size in the tree views... */
 #define ICON_SIZE 20
@@ -354,6 +365,8 @@ gtk_file_chooser_default_finalize (GObject *object)
 {
   GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (object);
 
+  g_signal_handler_disconnect (impl->file_system, impl->volumes_changed_id);
+  impl->volumes_changed_id = 0;
   g_signal_handler_disconnect (impl->file_system, impl->bookmarks_changed_id);
   impl->bookmarks_changed_id = 0;
   g_object_unref (impl->file_system);
@@ -494,60 +507,62 @@ get_file_info (GtkFileSystem *file_system, const GtkFilePath *path, GError **err
   return info;
 }
 
-/* Inserts a path in the shortcuts tree, making a copy of it.  A position of -1
- * indicates the end of the tree.  If the label is NULL, then the display name
- * of a GtkFileInfo is used.
+/* Inserts a path in the shortcuts tree, making a copy of it; alternatively,
+ * inserts a volume.  A position of -1 indicates the end of the tree.
  */
 static gboolean
 shortcuts_insert_path (GtkFileChooserDefault *impl,
                       int                    pos,
+                      gboolean               is_volume,
+                      GtkFileSystemVolume   *volume,
                       const GtkFilePath     *path,
-                      gboolean               is_root,
                       const char            *label,
                       GError               **error)
 {
-  GtkFileInfo *info;
-  GtkFilePath *path_copy;
+  char *label_copy;
   GdkPixbuf *pixbuf;
+  gpointer data;
   GtkTreeIter iter;
 
-  /* FIXME: what if someone adds a shortcut to a root?  get_file_info() will not
-   * work in that case, I think...
-   */
-
-  if (is_root)
-    info = gtk_file_system_get_root_info (impl->file_system,
-                                         path,
-#if 0
-                                         GTK_FILE_INFO_DISPLAY_NAME | GTK_FILE_INFO_ICON,
-#else
-                                         GTK_FILE_INFO_DISPLAY_NAME,
-#endif
-                                         error);
+  if (is_volume)
+    {
+      data = volume;
+      label_copy = gtk_file_system_volume_get_display_name (impl->file_system, volume);
+      pixbuf = gtk_file_system_volume_render_icon (impl->file_system,
+                                                  volume,
+                                                  GTK_WIDGET (impl),
+                                                  ICON_SIZE,
+                                                  NULL);
+    }
   else
-    info = get_file_info (impl->file_system, path, error);
+    {
+      GtkFileInfo *info;
 
-  if (!info)
-    return FALSE;
-#if 0
-  pixbuf = gtk_file_info_render_icon (info, impl->shortcuts_tree, ICON_SIZE);
-#endif
-  /* FIXME: NULL GError */
-  pixbuf = gtk_file_system_render_icon (impl->file_system, path, GTK_WIDGET (impl), ICON_SIZE, NULL);
+      info = get_file_info (impl->file_system, path, error);
+      if (!info)
+       return FALSE;
 
-  gtk_tree_store_insert (impl->shortcuts_model, &iter, NULL, pos);
-  path_copy = gtk_file_path_copy (path);
+      data = gtk_file_path_copy (path);
+
+      if (label)
+       label_copy = g_strdup (label);
+      else
+       label_copy = g_strdup (gtk_file_info_get_display_name (info));
+
+      pixbuf = gtk_file_system_render_icon (impl->file_system, path, GTK_WIDGET (impl), ICON_SIZE, NULL);
+
+      gtk_file_info_free (info);
+    }
 
-  if (!label)
-    label = gtk_file_info_get_display_name (info);
+  gtk_tree_store_insert (impl->shortcuts_model, &iter, NULL, pos);
 
   gtk_tree_store_set (impl->shortcuts_model, &iter,
                      SHORTCUTS_COL_PIXBUF, pixbuf,
-                     SHORTCUTS_COL_NAME, label,
-                     SHORTCUTS_COL_PATH, path_copy,
+                     SHORTCUTS_COL_NAME, label_copy,
+                     SHORTCUTS_COL_PATH, data,
                      -1);
 
-  gtk_file_info_free (info);
+  g_free (label_copy);
 
   if (pixbuf)
     g_object_unref (pixbuf);
@@ -567,7 +582,7 @@ shortcuts_append_home (GtkFileChooserDefault *impl)
   home_path = gtk_file_system_filename_to_path (impl->file_system, home);
 
   error = NULL;
-  impl->has_home = shortcuts_insert_path (impl, -1, home_path, FALSE, _("Home"), &error);
+  impl->has_home = shortcuts_insert_path (impl, -1, FALSE, NULL, home_path, _("Home"), &error);
   if (!impl->has_home)
     error_getting_info_dialog (impl, home_path, error);
 
@@ -587,7 +602,7 @@ shortcuts_append_desktop (GtkFileChooserDefault *impl)
   path = gtk_file_system_filename_to_path (impl->file_system, name);
   g_free (name);
 
-  impl->has_desktop = shortcuts_insert_path (impl, -1, path, FALSE, NULL, NULL);
+  impl->has_desktop = shortcuts_insert_path (impl, -1, FALSE, NULL, path, NULL, NULL);
   /* We do not actually pop up an error dialog if there is no desktop directory
    * because some people may really not want to have one.
    */
@@ -598,8 +613,7 @@ shortcuts_append_desktop (GtkFileChooserDefault *impl)
 /* Appends a list of GtkFilePath to the shortcuts model; returns how many were inserted */
 static int
 shortcuts_append_paths (GtkFileChooserDefault *impl,
-                       GSList                *paths,
-                       gboolean               is_file_system_root)
+                       GSList                *paths)
 {
   int num_inserted;
 
@@ -613,7 +627,7 @@ shortcuts_append_paths (GtkFileChooserDefault *impl,
       path = paths->data;
       error = NULL;
 
-      if (shortcuts_insert_path (impl, -1, path, is_file_system_root, NULL, &error))
+      if (shortcuts_insert_path (impl, -1, FALSE, NULL, path, NULL, &error))
        num_inserted++;
       else
        error_getting_info_dialog (impl, path, error);
@@ -622,62 +636,160 @@ shortcuts_append_paths (GtkFileChooserDefault *impl,
   return num_inserted;
 }
 
-/* Appends all the file system roots to the shortcuts model */
-static void
-shortcuts_append_file_system_roots (GtkFileChooserDefault *impl)
+/* Returns the index for the corresponding item in the shortcuts bar */
+static int
+shortcuts_get_index (GtkFileChooserDefault *impl,
+                    ShortcutsIndex         where)
 {
-  GSList *roots;
+  int n;
 
-  roots = gtk_file_system_list_roots (impl->file_system);
-  /* FIXME: handle the roots-changed signal on the file system */
+  n = 0;
+
+  if (where == SHORTCUTS_HOME)
+    goto out;
+  
+  n += impl->has_home ? 1 : 0;
+
+  if (where == SHORTCUTS_DESKTOP)
+    goto out;
+
+  n += impl->has_desktop ? 1 : 0;
+
+  if (where == SHORTCUTS_VOLUMES)
+    goto out;
+
+  n += impl->num_volumes;
+
+  if (where == SHORTCUTS_SHORTCUTS)
+    goto out;
 
-  impl->num_roots = shortcuts_append_paths (impl, roots, TRUE);
-  gtk_file_paths_free (roots);
+  n += impl->num_shortcuts;
+
+  if (where == SHORTCUTS_SEPARATOR)
+    goto out;
+
+  n += 1;
+
+  if (where == SHORTCUTS_BOOKMARKS)
+    goto out;
+
+  g_assert_not_reached ();
+
+ out:
+
+  return n;
 }
 
-/* Removes the bookmarks separator node and all the bookmarks from the tree
- * model.
- */
+typedef void (* RemoveFunc) (GtkFileChooserDefault *impl, gpointer data);
+
+/* Removes the specified number of rows from the shortcuts list */
 static void
-remove_bookmark_rows (GtkFileChooserDefault *impl)
+shortcuts_remove_rows (GtkFileChooserDefault *impl,
+                      int start_row,
+                      int n_rows,
+                      RemoveFunc remove_fn)
 {
   GtkTreePath *path;
-  GtkTreeIter iter;
 
-  if (!impl->bookmarks_set)
-    return;
+  path = gtk_tree_path_new_from_indices (start_row, -1);
 
-  /* Ugh.  Is there a better way to do this? */
+  for (; n_rows; n_rows--)
+    {
+      GtkTreeIter iter;
+      gpointer data;
 
-  path = gtk_tree_model_get_path (GTK_TREE_MODEL (impl->shortcuts_model), &impl->bookmarks_iter);
+      if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->shortcuts_model), &iter, path))
+       g_assert_not_reached ();
 
-  while (gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->shortcuts_model), &iter, path))
-    gtk_tree_store_remove (impl->shortcuts_model, &impl->bookmarks_iter);
+      if (remove_fn)
+       {
+         gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model), &iter, SHORTCUTS_COL_PATH, &data, -1);
+         (* remove_fn) (impl, data);
+       }
 
-  impl->bookmarks_set = FALSE;
+      gtk_tree_store_remove (impl->shortcuts_model, &iter);
+    }
+
+  gtk_tree_path_free (path);
 }
 
-/* Appends the bookmarks separator node and the bookmarks from the file system. */
+/* Used from shortcuts_remove_rows() */
 static void
-shortcuts_append_bookmarks (GtkFileChooserDefault *impl)
+volume_remove_cb (GtkFileChooserDefault *impl, gpointer data)
+{
+  GtkFileSystemVolume *volume;
+
+  volume = data;
+  gtk_file_system_volume_free (impl->file_system, volume);
+}
+
+/* Adds all the file system volumes to the shortcuts model */
+static void
+shortcuts_add_volumes (GtkFileChooserDefault *impl)
+{
+  int start_row;
+  GSList *list, *l;
+  int n;
+
+  start_row = shortcuts_get_index (impl, SHORTCUTS_VOLUMES);
+  shortcuts_remove_rows (impl, start_row, impl->num_volumes, volume_remove_cb);
+  impl->num_volumes = 0;
+
+  list = gtk_file_system_list_volumes (impl->file_system);
+
+  n = 0;
+
+  for (l = list; l; l = l->next)
+    {
+      GtkFileSystemVolume *volume;
+
+      volume = l->data;
+
+      shortcuts_insert_path (impl, start_row + n, TRUE, volume, NULL, NULL, NULL);
+      n++;
+    }
+
+  impl->num_volumes = n;
+}
+
+/* Used from shortcuts_remove_rows() */
+static void
+remove_bookmark_cb (GtkFileChooserDefault *impl, gpointer data)
+{
+  GtkFilePath *path;
+
+  path = data;
+  gtk_file_path_free (path);
+}
+
+/* Updates the list of bookmarks */
+static void
+shortcuts_add_bookmarks (GtkFileChooserDefault *impl)
 {
   GSList *bookmarks;
 
-  remove_bookmark_rows (impl);
+  shortcuts_remove_rows (impl,
+                        shortcuts_get_index (impl, SHORTCUTS_BOOKMARKS),
+                        impl->num_bookmarks,
+                        remove_bookmark_cb);
+
+  bookmarks = gtk_file_system_list_bookmarks (impl->file_system);
+  impl->num_bookmarks = shortcuts_append_paths (impl, bookmarks);
+  gtk_file_paths_free (bookmarks);
+}
+
+/* Appends the bookmarks separator node and the bookmarks from the file system. */
+static void
+shortcuts_append_bookmarks (GtkFileChooserDefault *impl)
+{
+  GtkTreeIter iter;
 
-  gtk_tree_store_append (impl->shortcuts_model, &impl->bookmarks_iter, NULL);
-  gtk_tree_store_set (impl->shortcuts_model, &impl->bookmarks_iter,
+  gtk_tree_store_append (impl->shortcuts_model, &iter, NULL);
+  gtk_tree_store_set (impl->shortcuts_model, &iter,
                      SHORTCUTS_COL_PIXBUF, NULL,
                      SHORTCUTS_COL_NAME, NULL,
                      SHORTCUTS_COL_PATH, NULL,
                      -1);
-  impl->bookmarks_set = TRUE;
-
-  bookmarks = gtk_file_system_list_bookmarks (impl->file_system);
-
-  /* FIXME: How do we know if a bookmark is a file system root? */
-  impl->num_bookmarks = shortcuts_append_paths (impl, bookmarks, FALSE);
-  gtk_file_paths_free (bookmarks);
 }
 
 /* Creates the GtkTreeStore used as the shortcuts model */
@@ -691,13 +803,13 @@ create_shortcuts_model (GtkFileChooserDefault *impl)
   impl->shortcuts_model = gtk_tree_store_new (SHORTCUTS_COL_NUM_COLUMNS,
                                              GDK_TYPE_PIXBUF,  /* pixbuf */
                                              G_TYPE_STRING,    /* name */
-                                             G_TYPE_POINTER);  /* path */
+                                             G_TYPE_POINTER);  /* path or volume */
 
   if (impl->file_system)
     {
       shortcuts_append_home (impl);
       shortcuts_append_desktop (impl);
-      shortcuts_append_file_system_roots (impl);
+      shortcuts_add_volumes (impl);
       shortcuts_append_bookmarks (impl);
     }
 
@@ -904,20 +1016,51 @@ add_bookmark_button_clicked_cb (GtkButton *button,
   shortcuts_add_bookmark_from_path (impl, impl->current_folder);
 }
 
+/* Returns the index of the selected row in the shortcuts list, or -1 if nothing
+ * is selected.
+ */
+static int
+shortcuts_get_selected_index (GtkFileChooserDefault *impl)
+{
+  GtkTreeSelection *selection;
+  GtkTreeIter iter;
+  GtkTreePath *path;
+  int *indices;
+  int idx;
+
+  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->shortcuts_tree));
+
+  if (!gtk_tree_selection_get_selected (selection, NULL, &iter))
+    return -1;
+
+  path = gtk_tree_model_get_path (GTK_TREE_MODEL (impl->shortcuts_model), &iter);
+  g_assert (path != NULL);
+
+  indices = gtk_tree_path_get_indices (path);
+  g_assert (gtk_tree_path_get_depth (path) == 1);
+
+  idx = *indices;
+
+  gtk_tree_path_free (path);
+
+  return idx;
+}
+
 /* Callback used when the "Remove bookmark" button is clicked */
 static void
 remove_bookmark_button_clicked_cb (GtkButton *button,
                                   GtkFileChooserDefault *impl)
 {
-  GtkTreeSelection *selection;
   GtkTreeIter iter;
   GtkFilePath *path;
+  int selected, start_row;
   GError *error;
 
-  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->shortcuts_tree));
+  selected = shortcuts_get_selected_index (impl);
 
-  if (!gtk_tree_selection_get_selected (selection, NULL, &iter))
-    return;
+  start_row = shortcuts_get_index (impl, SHORTCUTS_BOOKMARKS);
+  if (selected < start_row || selected >= start_row + impl->num_bookmarks)
+    g_assert_not_reached ();
 
   gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model), &iter, SHORTCUTS_COL_PATH, &path, -1);
 
@@ -937,23 +1080,59 @@ bookmarks_check_add_sensitivity (GtkFileChooserDefault *impl)
 {
   GtkTreeIter iter;
   gboolean exists;
+  int volumes_idx;
+  int separator_idx;
 
   exists = FALSE;
 
   if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (impl->shortcuts_model), &iter))
-    do
-      {
-       GtkFilePath *path;
+    {
+      int i;
 
-       gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model), &iter, SHORTCUTS_COL_PATH, &path, -1);
+      separator_idx = shortcuts_get_index (impl, SHORTCUTS_SEPARATOR);
+      volumes_idx = shortcuts_get_index (impl, SHORTCUTS_VOLUMES);
 
-       if (path && gtk_file_path_compare (path, impl->current_folder) == 0)
-         {
-           exists = TRUE;
-           break;
-         }
-      }
-    while (gtk_tree_model_iter_next (GTK_TREE_MODEL (impl->shortcuts_model), &iter));
+      i = 0;
+
+      do
+       {
+         gpointer data;
+
+         if (i == separator_idx)
+           continue;
+
+         gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model), &iter, SHORTCUTS_COL_PATH, &data, -1);
+
+         if (i >= volumes_idx && i < volumes_idx + impl->num_volumes)
+           {
+             GtkFileSystemVolume *volume;
+             GtkFilePath *base_path;
+
+             volume = data;
+             base_path = gtk_file_system_volume_get_base_path (impl->file_system, volume);
+
+             exists = strcmp (gtk_file_path_get_string (impl->current_folder),
+                              gtk_file_path_get_string (base_path)) == 0;
+             g_free (base_path);
+
+             if (exists)
+               break;
+           }
+         else
+           {
+             GtkFilePath *path;
+
+             path = data;
+
+             if (path && gtk_file_path_compare (path, impl->current_folder) == 0)
+               {
+                 exists = TRUE;
+                 break;
+               }
+           }
+       }
+      while (gtk_tree_model_iter_next (GTK_TREE_MODEL (impl->shortcuts_model), &iter));
+    }
 
   gtk_widget_set_sensitive (impl->add_bookmark_button, !exists);
 }
@@ -964,28 +1143,13 @@ bookmarks_check_add_sensitivity (GtkFileChooserDefault *impl)
 static void
 bookmarks_check_remove_sensitivity (GtkFileChooserDefault *impl)
 {
-  GtkTreeSelection *selection;
-  GtkTreeIter iter;
+  int selected, start_row;
   gboolean is_bookmark;
 
-  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->shortcuts_tree));
+  selected = shortcuts_get_selected_index (impl);
+  start_row = shortcuts_get_index (impl, SHORTCUTS_BOOKMARKS);
 
-  if (gtk_tree_selection_get_selected (selection, NULL, &iter))
-    {
-      GtkTreePath *bookmarks_path;
-      GtkTreePath *sel_path;
-
-      bookmarks_path = gtk_tree_model_get_path (GTK_TREE_MODEL (impl->shortcuts_model),
-                                               &impl->bookmarks_iter);
-      sel_path = gtk_tree_model_get_path (GTK_TREE_MODEL (impl->shortcuts_model), &iter);
-
-      is_bookmark = (gtk_tree_path_compare (bookmarks_path, sel_path) < 0);
-
-      gtk_tree_path_free (bookmarks_path);
-      gtk_tree_path_free (sel_path);
-    }
-  else
-    is_bookmark = FALSE;
+  is_bookmark = (selected >= start_row) && (selected < start_row + impl->num_bookmarks);
 
   gtk_widget_set_sensitive (impl->remove_bookmark_button, is_bookmark);
 }
@@ -1435,12 +1599,19 @@ set_extra_widget (GtkFileChooserDefault *impl,
     }
 }
 
+static void
+volumes_changed_cb (GtkFileSystem         *file_system,
+                   GtkFileChooserDefault *impl)
+{
+  shortcuts_add_volumes (impl);
+}
+
 /* Callback used when the set of bookmarks changes in the file system */
 static void
 bookmarks_changed_cb (GtkFileSystem         *file_system,
                      GtkFileChooserDefault *impl)
 {
-  shortcuts_append_bookmarks (impl);
+  shortcuts_add_bookmarks (impl);
 
   bookmarks_check_add_sensitivity (impl);
   bookmarks_check_remove_sensitivity (impl);
@@ -1467,6 +1638,8 @@ gtk_file_chooser_default_set_property (GObject      *object,
          {
            if (impl->file_system)
              {
+               g_signal_handler_disconnect (impl->file_system, impl->volumes_changed_id);
+               impl->volumes_changed_id = 0;
                g_signal_handler_disconnect (impl->file_system, impl->bookmarks_changed_id);
                impl->bookmarks_changed_id = 0;
                g_object_unref (impl->file_system);
@@ -1475,6 +1648,9 @@ gtk_file_chooser_default_set_property (GObject      *object,
            if (impl->file_system)
              {
                g_object_ref (impl->file_system);
+               impl->volumes_changed_id = g_signal_connect (impl->file_system, "volumes-changed",
+                                                            G_CALLBACK (volumes_changed_cb),
+                                                            impl);
                impl->bookmarks_changed_id = g_signal_connect (impl->file_system, "bookmarks-changed",
                                                               G_CALLBACK (bookmarks_changed_cb),
                                                               impl);
@@ -2173,9 +2349,7 @@ static int
 shortcuts_get_pos_for_shortcut_folder (GtkFileChooserDefault *impl,
                                       int                    pos)
 {
-  return pos + ((impl->has_home ? 1 : 0)
-               + (impl->has_desktop ? 1 : 0)
-               + impl->num_roots);
+  return pos + shortcuts_get_index (impl, SHORTCUTS_SHORTCUTS);
 }
 
 static gboolean
@@ -2189,8 +2363,7 @@ gtk_file_chooser_default_add_shortcut_folder (GtkFileChooser    *chooser,
 
   pos = shortcuts_get_pos_for_shortcut_folder (impl, impl->num_shortcuts);
 
-  /* FIXME: how do we know if the path is a file system root? */
-  result = shortcuts_insert_path (impl, pos, path, FALSE, NULL, error);
+  result = shortcuts_insert_path (impl, pos, FALSE, NULL, path, NULL, error);
 
   if (result)
     impl->num_shortcuts++;
@@ -2446,6 +2619,40 @@ tree_selection_changed (GtkTreeSelection      *selection,
     _gtk_file_chooser_set_current_folder_path (GTK_FILE_CHOOSER (impl), file_path);
 }
 
+/* Activates a volume by mounting it if necessary and then switching to its
+ * base path.
+ */
+static void
+shortcuts_activate_volume (GtkFileChooserDefault *impl,
+                          GtkFileSystemVolume   *volume)
+{
+  GtkFilePath *path;
+
+  if (!gtk_file_system_volume_get_is_mounted (impl->file_system, volume))
+    {
+      GError *error;
+
+      error = NULL;
+      if (!gtk_file_system_volume_mount (impl->file_system, volume, &error))
+       {
+         char *msg;
+
+         msg = g_strdup_printf ("Could not mount %s:\n%s",
+                                gtk_file_system_volume_get_display_name (impl->file_system, volume),
+                                error->message);
+         error_message (impl, msg);
+         g_free (msg);
+         g_error_free (error);
+
+         return;
+       }
+    }
+
+  path = gtk_file_system_volume_get_base_path (impl->file_system, volume);
+  _gtk_file_chooser_set_current_folder_path (GTK_FILE_CHOOSER (impl), path);
+  gtk_file_path_free (path);
+}
+
 /* Callback used when a row in the shortcuts list is activated */
 static void
 shortcuts_row_activated_cb (GtkTreeView           *tree_view,
@@ -2454,22 +2661,34 @@ shortcuts_row_activated_cb (GtkTreeView           *tree_view,
                            GtkFileChooserDefault *impl)
 {
   GtkTreeIter iter;
-  GtkFilePath *model_path;
+  int selected, start_row;
+  gpointer data;
   
   if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->shortcuts_model), &iter, path))
     return;
 
-  /* Set the current folder */
+  selected = *gtk_tree_path_get_indices (path);
 
-  gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model), &iter, SHORTCUTS_COL_PATH, &model_path, -1);
+  if (selected == shortcuts_get_index (impl, SHORTCUTS_SEPARATOR))
+    return;
+
+  gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model), &iter, SHORTCUTS_COL_PATH, &data, -1);
 
-  if (!model_path)
+  start_row = shortcuts_get_index (impl, SHORTCUTS_VOLUMES);
+  if (selected >= start_row && selected < start_row + impl->num_volumes)
     {
-      /* We are on the bookmarks separator node, so do nothing */
-      return;
+      GtkFileSystemVolume *volume;
+
+      volume = data;
+      shortcuts_activate_volume (impl, volume);
     }
+  else
+    {
+      GtkFilePath *file_path;
 
-  _gtk_file_chooser_set_current_folder_path (GTK_FILE_CHOOSER (impl), model_path);
+      file_path = data;
+      _gtk_file_chooser_set_current_folder_path (GTK_FILE_CHOOSER (impl), file_path);
+    }
 }
 
 static gboolean
@@ -2480,16 +2699,8 @@ shortcuts_select_func  (GtkTreeSelection  *selection,
                        gpointer           data)
 {
   GtkFileChooserDefault *impl = data;
-  GtkTreeIter iter;
-  GtkFilePath *model_path;
-
-  if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->shortcuts_model), &iter, path))
-    return FALSE;
-
-  gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model), &iter, SHORTCUTS_COL_PATH, &model_path, -1);
 
-  /* Don't allow the separator node to be selected */
-  return model_path != NULL;
+  return (*gtk_tree_path_get_indices (path) != shortcuts_get_index (impl, SHORTCUTS_SEPARATOR));
 }
 
 static void
index c927029d06f17bc6780b2ee62361d88ea2ec1182..691941b42a94a5f57bb67cf7b7c0a9acd26279cc 100644 (file)
@@ -447,6 +447,13 @@ gtk_file_system_base_init (gpointer g_class)
     {
       GType iface_type = G_TYPE_FROM_INTERFACE (g_class);
 
+      g_signal_new ("volumes-changed",
+                   iface_type,
+                   G_SIGNAL_RUN_LAST,
+                   G_STRUCT_OFFSET (GtkFileSystemIface, volumes_changed),
+                   NULL, NULL,
+                   g_cclosure_marshal_VOID__VOID,
+                   G_TYPE_NONE, 0);
       g_signal_new ("roots-changed",
                    iface_type,
                    G_SIGNAL_RUN_LAST,
@@ -466,6 +473,14 @@ gtk_file_system_base_init (gpointer g_class)
     }
 }
 
+GSList *
+gtk_file_system_list_volumes (GtkFileSystem  *file_system)
+{
+  g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), NULL);
+
+  return GTK_FILE_SYSTEM_GET_IFACE (file_system)->list_volumes (file_system);
+}
+
 GSList *
 gtk_file_system_list_roots (GtkFileSystem  *file_system)
 {
@@ -512,6 +527,142 @@ gtk_file_system_create_folder(GtkFileSystem     *file_system,
   return GTK_FILE_SYSTEM_GET_IFACE (file_system)->create_folder (file_system, path, error);
 }
 
+/**
+ * gtk_file_system_volume_free:
+ * @file_system: a #GtkFileSystem
+ * @volume: a #GtkFileSystemVolume
+ * 
+ * Frees a #GtkFileSystemVolume structure as returned by
+ * gtk_file_system_list_volumes().
+ **/
+void
+gtk_file_system_volume_free (GtkFileSystem       *file_system,
+                            GtkFileSystemVolume *volume)
+{
+  g_return_if_fail (GTK_IS_FILE_SYSTEM (file_system));
+  g_return_if_fail (volume != NULL);
+
+  GTK_FILE_SYSTEM_GET_IFACE (file_system)->volume_free (file_system, volume);
+}
+
+/**
+ * gtk_file_system_volume_get_base_path:
+ * @file_system: a #GtkFileSystem
+ * @volume: a #GtkFileSystemVolume
+ * 
+ * Queries the base path for a volume.  For example, a CD-ROM device may yield a
+ * path of "/mnt/cdrom".
+ * 
+ * Return value: a #GtkFilePath with the base mount path of the specified
+ * @volume.
+ **/
+GtkFilePath *
+gtk_file_system_volume_get_base_path (GtkFileSystem       *file_system,
+                                     GtkFileSystemVolume *volume)
+{
+  g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), NULL);
+  g_return_val_if_fail (volume != NULL, NULL);
+
+  return GTK_FILE_SYSTEM_GET_IFACE (file_system)->volume_get_base_path (file_system, volume);
+}
+
+/**
+ * gtk_file_system_volume_get_is_mounted:
+ * @file_system: a #GtkFileSystem
+ * @volume: a #GtkFileSystemVolume
+ * 
+ * Queries whether a #GtkFileSystemVolume is mounted or not.  If it is not, it
+ * can be mounted with gtk_file_system_volume_mount().
+ * 
+ * Return value: TRUE if the @volume is mounted, FALSE otherwise.
+ **/
+gboolean
+gtk_file_system_volume_get_is_mounted (GtkFileSystem       *file_system,
+                                      GtkFileSystemVolume *volume)
+{
+  g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), FALSE);
+  g_return_val_if_fail (volume != NULL, FALSE);
+
+  return GTK_FILE_SYSTEM_GET_IFACE (file_system)->volume_get_is_mounted (file_system, volume);
+}
+
+/**
+ * gtk_file_system_volume_mount:
+ * @file_system: a #GtkFileSystem
+ * @volume: a #GtkFileSystemVolume
+ * @error: location to store error, or %NULL
+ * 
+ * Tries to mount an unmounted volume.  This may cause the "volumes-changed"
+ * signal in the @file_system to be emitted.
+ * 
+ * Return value: TRUE if the @volume was mounted successfully, FALSE otherwise.
+ **/
+gboolean
+gtk_file_system_volume_mount (GtkFileSystem        *file_system, 
+                             GtkFileSystemVolume  *volume,
+                             GError              **error)
+{
+  g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), FALSE);
+  g_return_val_if_fail (volume != NULL, FALSE);
+  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+  return GTK_FILE_SYSTEM_GET_IFACE (file_system)->volume_mount (file_system, volume, error);
+}
+
+/**
+ * gtk_file_system_volume_get_display_name:
+ * @file_system: a #GtkFileSystem
+ * @volume: a #GtkFileSystemVolume
+ * 
+ * Queries the human-readable name for a @volume.  This string can be displayed
+ * in a list of volumes that can be accessed, for example.
+ * 
+ * Return value: A string with the human-readable name for a #GtkFileSystemVolume.
+ **/
+char *
+gtk_file_system_volume_get_display_name (GtkFileSystem        *file_system, 
+                                        GtkFileSystemVolume  *volume)
+{
+  g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), NULL);
+  g_return_val_if_fail (volume != NULL, NULL);
+
+  return GTK_FILE_SYSTEM_GET_IFACE (file_system)->volume_get_display_name (file_system, volume);
+}
+
+/**
+ * gtk_file_system_volume_render_icon:
+ * @file_system: a #GtkFileSystem
+ * @volume: a #GtkFileSystemVolume
+ * @widget: Reference widget to render icons.
+ * @pixel_size: Size of the icon.
+ * @error: location to store error, or %NULL
+ * 
+ * Renders an icon suitable for a file #GtkFileSystemVolume.
+ * 
+ * Return value: A #GdkPixbuf containing an icon, or NULL if the icon could not
+ * be rendered.  In the latter case, the @error value will be set as
+ * appropriate.
+ **/
+GdkPixbuf *
+gtk_file_system_volume_render_icon (GtkFileSystem        *file_system,
+                                   GtkFileSystemVolume  *volume,
+                                   GtkWidget            *widget,
+                                   gint                  pixel_size,
+                                   GError              **error)
+{
+  g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), NULL);
+  g_return_val_if_fail (volume != NULL, NULL);
+  g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
+  g_return_val_if_fail (pixel_size > 0, NULL);
+  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+  return GTK_FILE_SYSTEM_GET_IFACE (file_system)->volume_render_icon (file_system,
+                                                                     volume,
+                                                                     widget,
+                                                                     pixel_size,
+                                                                     error);
+}
+
 /**
  * gtk_file_system_get_parent:
  * @file_system: a #GtkFileSystem
@@ -680,7 +831,7 @@ gtk_file_system_render_icon (GtkFileSystem      *file_system,
 {
   g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), NULL);
   g_return_val_if_fail (path != NULL, NULL);
-  g_return_val_if_fail (widget != NULL, NULL);
+  g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
   g_return_val_if_fail (pixel_size > 0, NULL);
 
   return GTK_FILE_SYSTEM_GET_IFACE (file_system)->render_icon (file_system, path, widget, pixel_size, error);
index e3c061870d772b4a27e91e51ea527f6b7c130b00..394938864533f26b11052c521cbe96c1c67ada5c 100644 (file)
@@ -36,11 +36,12 @@ G_BEGIN_DECLS
 
 typedef gint64 GtkFileTime;
 
-typedef struct _GtkFileFolder      GtkFileFolder;
-typedef struct _GtkFileFolderIface GtkFileFolderIface;
-typedef struct _GtkFileInfo        GtkFileInfo;
-typedef struct _GtkFileSystem      GtkFileSystem;
-typedef struct _GtkFileSystemIface GtkFileSystemIface;
+typedef struct _GtkFileFolder       GtkFileFolder;
+typedef struct _GtkFileFolderIface  GtkFileFolderIface;
+typedef struct _GtkFileInfo         GtkFileInfo;
+typedef struct _GtkFileSystem       GtkFileSystem;
+typedef struct _GtkFileSystemIface  GtkFileSystemIface;
+typedef struct _GtkFileSystemVolume GtkFileSystemVolume;
 
 typedef struct _GtkFilePath        GtkFilePath;
 
@@ -143,6 +144,7 @@ struct _GtkFileSystemIface
 
   /* Methods
    */
+  GSList *           (*list_volumes)   (GtkFileSystem     *file_system);
   GSList *           (*list_roots)     (GtkFileSystem     *file_system);
 
   GtkFileInfo *      (*get_root_info)  (GtkFileSystem     *file_system,
@@ -158,6 +160,26 @@ struct _GtkFileSystemIface
                                        const GtkFilePath *path,
                                        GError           **error);
 
+  /* Volumes
+   */
+
+  void          (*volume_free)             (GtkFileSystem        *file_system,
+                                           GtkFileSystemVolume  *volume);
+  GtkFilePath * (*volume_get_base_path)    (GtkFileSystem        *file_system,
+                                           GtkFileSystemVolume  *volume);
+  gboolean      (*volume_get_is_mounted)   (GtkFileSystem        *file_system,
+                                           GtkFileSystemVolume  *volume);
+  gboolean      (*volume_mount)            (GtkFileSystem        *file_system, 
+                                           GtkFileSystemVolume  *volume,
+                                           GError              **error);
+  char *        (*volume_get_display_name) (GtkFileSystem        *file_system, 
+                                           GtkFileSystemVolume  *volume);
+  GdkPixbuf *   (*volume_render_icon)      (GtkFileSystem        *file_system,
+                                           GtkFileSystemVolume  *volume,
+                                           GtkWidget            *widget,
+                                           gint                  pixel_size,
+                                           GError              **error);
+
   /* Path Manipulation
    */
   gboolean      (*get_parent)      (GtkFileSystem      *file_system,
@@ -203,18 +225,37 @@ struct _GtkFileSystemIface
 
   /* Signals
    */
+  void (*volumes_changed)   (GtkFileSystem *file_system);
   void (*roots_changed)     (GtkFileSystem *file_system);
   void (*bookmarks_changed) (GtkFileSystem *file_system);
 };
 
 GType             gtk_file_system_get_type       (void);
 
+GSList *          gtk_file_system_list_volumes   (GtkFileSystem     *file_system);
 GSList *          gtk_file_system_list_roots     (GtkFileSystem     *file_system);
 GtkFileInfo *     gtk_file_system_get_root_info  (GtkFileSystem     *file_system,
                                                  const GtkFilePath *path,
                                                  GtkFileInfoType    types,
                                                  GError           **error);
 
+void              gtk_file_system_volume_free             (GtkFileSystem        *file_system,
+                                                          GtkFileSystemVolume  *volume);
+GtkFilePath *     gtk_file_system_volume_get_base_path    (GtkFileSystem        *file_system,
+                                                          GtkFileSystemVolume  *volume);
+gboolean          gtk_file_system_volume_get_is_mounted   (GtkFileSystem        *file_system,
+                                                          GtkFileSystemVolume  *volume);
+gboolean          gtk_file_system_volume_mount            (GtkFileSystem        *file_system, 
+                                                          GtkFileSystemVolume  *volume,
+                                                          GError              **error);
+char *            gtk_file_system_volume_get_display_name (GtkFileSystem        *file_system, 
+                                                          GtkFileSystemVolume  *volume);
+GdkPixbuf *       gtk_file_system_volume_render_icon      (GtkFileSystem        *file_system,
+                                                          GtkFileSystemVolume  *volume,
+                                                          GtkWidget            *widget,
+                                                          gint                  pixel_size,
+                                                          GError              **error);
+
 gboolean          gtk_file_system_get_parent     (GtkFileSystem     *file_system,
                                                  const GtkFilePath *path,
                                                  GtkFilePath      **parent,
index d0a1924c4690a05eb9be74f2d22bdf5e9d9fc869..2eb9744d709da33f9e1466ec0039409fec6bfbe3 100644 (file)
@@ -47,6 +47,11 @@ struct _GtkFileSystemUnix
   GObject parent_instance;
 };
 
+/* Simple stub for our returned volumes */
+typedef struct {
+  int dummy;
+} Volume;
+
 #define GTK_TYPE_FILE_FOLDER_UNIX             (gtk_file_folder_unix_get_type ())
 #define GTK_FILE_FOLDER_UNIX(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_FILE_FOLDER_UNIX, GtkFileFolderUnix))
 #define GTK_IS_FILE_FOLDER_UNIX(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_FILE_FOLDER_UNIX))
@@ -78,6 +83,7 @@ static void gtk_file_system_unix_iface_init   (GtkFileSystemIface     *iface);
 static void gtk_file_system_unix_init         (GtkFileSystemUnix      *impl);
 static void gtk_file_system_unix_finalize     (GObject                *object);
 
+static GSList *       gtk_file_system_unix_list_volumes  (GtkFileSystem      *file_system);
 static GSList *       gtk_file_system_unix_list_roots    (GtkFileSystem      *file_system);
 static GtkFileInfo *  gtk_file_system_unix_get_root_info (GtkFileSystem      *file_system,
                                                          const GtkFilePath  *path,
@@ -90,6 +96,24 @@ static GtkFileFolder *gtk_file_system_unix_get_folder    (GtkFileSystem      *fi
 static gboolean       gtk_file_system_unix_create_folder (GtkFileSystem      *file_system,
                                                          const GtkFilePath  *path,
                                                          GError            **error);
+
+static void         gtk_file_system_unix_volume_free             (GtkFileSystem       *file_system,
+                                                                 GtkFileSystemVolume *volume);
+static GtkFilePath *gtk_file_system_unix_volume_get_base_path    (GtkFileSystem       *file_system,
+                                                                 GtkFileSystemVolume *volume);
+static gboolean     gtk_file_system_unix_volume_get_is_mounted   (GtkFileSystem       *file_system,
+                                                                 GtkFileSystemVolume *volume);
+static gboolean     gtk_file_system_unix_volume_mount            (GtkFileSystem       *file_system,
+                                                                 GtkFileSystemVolume *volume,
+                                                                 GError             **error);
+static gchar *      gtk_file_system_unix_volume_get_display_name (GtkFileSystem       *file_system,
+                                                                 GtkFileSystemVolume *volume);
+static GdkPixbuf *  gtk_file_system_unix_volume_render_icon      (GtkFileSystem        *file_system,
+                                                                 GtkFileSystemVolume  *volume,
+                                                                 GtkWidget            *widget,
+                                                                 gint                  pixel_size,
+                                                                 GError              **error);
+
 static gboolean       gtk_file_system_unix_get_parent    (GtkFileSystem      *file_system,
                                                          const GtkFilePath  *path,
                                                          GtkFilePath       **parent,
@@ -218,10 +242,17 @@ gtk_file_system_unix_class_init (GtkFileSystemUnixClass *class)
 static void
 gtk_file_system_unix_iface_init   (GtkFileSystemIface *iface)
 {
+  iface->list_volumes = gtk_file_system_unix_list_volumes;
   iface->list_roots = gtk_file_system_unix_list_roots;
   iface->get_folder = gtk_file_system_unix_get_folder;
   iface->get_root_info = gtk_file_system_unix_get_root_info;
   iface->create_folder = gtk_file_system_unix_create_folder;
+  iface->volume_free = gtk_file_system_unix_volume_free;
+  iface->volume_get_base_path = gtk_file_system_unix_volume_get_base_path;
+  iface->volume_get_is_mounted = gtk_file_system_unix_volume_get_is_mounted;
+  iface->volume_mount = gtk_file_system_unix_volume_mount;
+  iface->volume_get_display_name = gtk_file_system_unix_volume_get_display_name;
+  iface->volume_render_icon = gtk_file_system_unix_volume_render_icon;
   iface->get_parent = gtk_file_system_unix_get_parent;
   iface->make_path = gtk_file_system_unix_make_path;
   iface->parse = gtk_file_system_unix_parse;
@@ -246,6 +277,12 @@ gtk_file_system_unix_finalize (GObject *object)
   system_parent_class->finalize (object);
 }
 
+static GSList *
+gtk_file_system_unix_list_volumes (GtkFileSystem *file_system)
+{
+  return g_slist_append (NULL, gtk_file_path_new_dup ("/"));
+}
+
 static GSList *
 gtk_file_system_unix_list_roots (GtkFileSystem *file_system)
 {
@@ -314,6 +351,59 @@ gtk_file_system_unix_create_folder (GtkFileSystem     *file_system,
   return result;
 }
 
+static void
+gtk_file_system_unix_volume_free (GtkFileSystem        *file_system,
+                                 GtkFileSystemVolume  *volume)
+{
+  GtkFilePath *path;
+
+  path = (GtkFilePath *) volume;
+  gtk_file_path_free (path);
+}
+
+static GtkFilePath *
+gtk_file_system_unix_volume_get_base_path (GtkFileSystem        *file_system,
+                                          GtkFileSystemVolume  *volume)
+{
+  return gtk_file_path_new_dup ("/");
+}
+
+static gboolean
+gtk_file_system_unix_volume_get_is_mounted (GtkFileSystem        *file_system,
+                                           GtkFileSystemVolume  *volume)
+{
+  return TRUE;
+}
+
+static gboolean
+gtk_file_system_unix_volume_mount (GtkFileSystem        *file_system, 
+                                  GtkFileSystemVolume  *volume,
+                                  GError              **error)
+{
+  g_set_error (error,
+              GTK_FILE_SYSTEM_ERROR,
+              GTK_FILE_SYSTEM_ERROR_FAILED,
+              _("This file system does not support mounting"));
+  return FALSE;
+}
+
+static gchar *
+gtk_file_system_unix_volume_get_display_name (GtkFileSystem       *file_system,
+                                             GtkFileSystemVolume *volume)
+{
+  return g_strdup (_("Filesystem")); /* Same as Nautilus */
+}
+
+static GdkPixbuf *
+gtk_file_system_unix_volume_render_icon (GtkFileSystem        *file_system,
+                                        GtkFileSystemVolume  *volume,
+                                        GtkWidget            *widget,
+                                        gint                  pixel_size,
+                                        GError              **error)
+{
+  return NULL; /* FIXME: We need a hard disk icon or something */
+}
+
 static gboolean
 gtk_file_system_unix_get_parent (GtkFileSystem     *file_system,
                                 const GtkFilePath *path,